/*
 * Applicaton.cpp
 *
 *  Created on: 18.11.2009
 *      Author: Sergej Schmidt
 *  wiederaufgenomen am: 16.04.2010
 */

#include "GameManager.h"
#include "Stats/GameState.h"

using namespace Ogre;

template<> GameManager* Singleton<GameManager>::ms_Singleton = 0;

GameManager::GameManager() {
	m_pRoot = 0;
	m_pInputManager = 0;
	m_pGui = 0;

}

GameManager::~GameManager() {
	// Отчистеть все States
	while(!m_vecStates.empty())
	{
		m_vecStates.back()->exit();
		m_vecStates.pop_back();
	}
	if(m_pOptionParser)
	{
		delete m_pOptionParser;
	}
	if(m_pSpracheParser)
	{
		delete m_pSpracheParser;
	}
	if( m_pGui )
	{
		m_pGui->shutdown();
		delete m_pGui;
		m_pGui = 0;
	}
	if(m_pInputManager)
		delete m_pInputManager;
	if(m_pRoot)
		delete m_pRoot;
}

void GameManager::start(GameState* state)
{
	m_pRoot = new Root("plugins.cfg", "../ogre.cfg", "Ogre.log");

	setupResources();

	if(!configure()) return;

	TextureManager::getSingleton().setDefaultNumMipmaps(5);
	ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

	m_pInputManager = InputManager::getSingletonPtr();
	m_pInputManager->initialise( m_pRenderWindow );

	m_pInputManager->addKeyListener( this, "GameManager" );
	m_pInputManager->addMouseListener( this, "GameManager" );

    m_pSceneManager = m_pRoot->createSceneManager( ST_GENERIC,StringUtil::BLANK );
    m_pCamera = m_pSceneManager->createCamera( "IntroCamera" );

    m_pViewport = m_pRoot->getAutoCreatedWindow()->addViewport( m_pCamera );
    m_pViewport->setBackgroundColour( ColourValue( 0.5, 0.5, 1.0 ) );

	// GUI
    m_pGui = new MyGUI::Gui();
	m_pGui->initialise(); // m_pRoot->getAutoCreatedWindow() ); /// TODO
    // загрузка настроек
    m_pOptionParser = new Parser("./Data/main.config");
    string sprachefile = m_pOptionParser->getString( "lang" + m_pOptionParser->getString("language") );
    m_pSpracheParser = new Parser( "./Data/" + sprachefile );

	m_pRoot->addFrameListener( this );

	changeState( state );

	m_pRoot->startRendering();
}

void GameManager::changeState(GameState* state)
{
	// Отчистеть текущие статы
	if( !m_vecStates.empty() )
	{
		m_vecStates.back()->exit();
		m_vecStates.pop_back();
	}
	// Сохранить и инициализировать новые статы
	m_vecStates.push_back( state );
	m_vecStates.back()->enter();
}

void GameManager::pushState(GameState* state)
{
	// Пузировать текущие статы
	if( !m_vecStates.empty() )
		m_vecStates.back()->pause();
	// Добавить и инициализировать новые статы
	m_vecStates.push_back( state );
	m_vecStates.back()->enter();
}

void GameManager::popState()
{
	// Отчистеть текущий стат
	if( !m_vecStates.empty() )
	{
		m_vecStates.back()->exit();
		m_vecStates.pop_back();
	}
	// востановить предидущий стат
	if( !m_vecStates.empty() )
	{
		m_vecStates.back()->resume();
	}
}

void GameManager::setupResources()
{
	// загрузить путь к рессурсам из файла конфигураций
	ConfigFile cf;
	cf.load("resources.cfg");

	ConfigFile::SectionIterator seci = cf.getSectionIterator();

	String secName, typeName, archName;
	while (seci.hasMoreElements())
	{
		secName = seci.peekNextKey();
		ConfigFile::SettingsMultiMap *settings = seci.getNext();
		ConfigFile::SettingsMultiMap::iterator i;
		for( i= settings->begin(); i!=settings->end(); ++i )
		{
			typeName = i->first;
			archName = i->second;
			ResourceGroupManager::getSingleton().addResourceLocation(
					archName, typeName, secName);
		}
	}
}

bool GameManager::configure()
{
	// загрузка настроек из Ogre.cfg
	if( !m_pRoot->restoreConfig() )
	{
		if(!m_pRoot->showConfigDialog())
		{
			return false;
		}
	}
	m_pRenderWindow = m_pRoot->initialise(true, "Game::Ogre");
	//ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
	return true;
}
bool GameManager::frameStarted(const Ogre::FrameEvent& evt)
{
	m_pInputManager->capture();
	return m_vecStates.back()->frameStarted( evt );
}

bool GameManager::frameEnded(const Ogre::FrameEvent& evt)
{
	return m_vecStates.back()->frameEnded( evt );
}

GameManager* GameManager::getSingletonPtr()
{
	return ms_Singleton;
}

GameManager& GameManager::getSingleton(void)
{
	assert( ms_Singleton );
	return *ms_Singleton;
}

// Поддержка клавиатуры
bool GameManager::keyPressed( const OIS::KeyEvent& e )
{
	// Вызов keyPressed актуального GameState
	m_vecStates.back()->keyPressed( e );
	return true;
}
bool GameManager::keyReleased( const OIS::KeyEvent& e )
{
	// Вызов keyReleased актуального GameState
	m_vecStates.back()->keyReleased( e );
	return true;
}
// Поддержка Мыши
bool GameManager::mouseMoved( const OIS::MouseEvent& e )
{
	m_vecStates.back()->mouseMoved( e );
	return true;
}
bool GameManager::mousePressed( const OIS::MouseEvent& e, OIS::MouseButtonID id )
{
	m_vecStates.back()->mousePressed( e, id );
	return true;
}
bool GameManager::mouseReleased( const OIS::MouseEvent& e, OIS::MouseButtonID id )
{
	m_vecStates.back()->mouseReleased( e, id );
	return true;
}

void GameManager::LoadSprache()
{
    string sprachefile = "./Data/" + m_pOptionParser->getString( "lang" + m_pOptionParser->getString("language") );
    m_pSpracheParser->Load( sprachefile );
    m_pSpracheParser->prepareMyGUI( m_pGui );
}
